package com.kclm.xsap.utils.time;

import com.kclm.xsap.entity.TimeEntity;

import java.time.Duration;
import java.time.LocalTime;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 判断时间冲突
 * 1. 当teacherSchedule为空，则可以直接添加新的课程时间
 * 2. 当teacherSchedule只有一个时间段，则
 * 检查新的课程结束的时间是否在已有的一个时间段之前或者与其相等，
 * 检查新的课程开始的时间是否在已有的一个时间段之后或者与其相等
 * 3. 当teacherSchedule有多个时间段，
 * 首先判断第二步的情况，如果成立，则可以直接添加新的课程时间
 * 其次判断课程开始的时间是否在已有的第一个时间段之后或者与其相等并且结束时间在第二个时间段之前如果成立，则
 * 遍历教师课程安排列表，找到与给定时间最接近的两个时间段，(这两个时间段是上一个课程结束时间和下一个课程开始时间)
 * 计算最接近的两个时间段之间的时间间隔，如果时间间隔大于等于课程时间，则可以添加新的课程时间，否则不可以
 */
public class ClassTimeUtil {
    public static boolean isAdd(List<TimeEntity> teacherSchedule, TimeEntity classTime) {

        System.out.println("teacherSchedule===>" + teacherSchedule);
        System.out.println("classTime===>" + classTime);
        //teacherSchedule===>[TimeEntity(startTime=19:20, endTime=20:20), TimeEntity(startTime=15:20, endTime=16:20), TimeEntity(startTime=11:30, endTime=12:25), TimeEntity(startTime=09:30, endTime=10:30), TimeEntity(startTime=01:30, endTime=02:30)]
        //classTime===>TimeEntity(startTime=09:30, endTime=10:30)

        // 如果教师的课程安排列表为空，则可以直接添加新的课程时间
        if (teacherSchedule.isEmpty()) {
            return true;
        }

        // 获取教师课程安排列表中的第一个时间和最后一个时间
        TimeEntity firstTimeEntity = teacherSchedule.get(teacherSchedule.size() - 1);
        TimeEntity lastTimeEntity = teacherSchedule.get(0);

        System.out.println("firstTimeEntity===>" + firstTimeEntity);
        System.out.println("lastTimeEntity===>" + lastTimeEntity);

        // 如果教师的课程安排列表只有一个时间段, startTime, endTime都属于统一时间
        if (teacherSchedule.size() == 1) {
            // 检查新的课程结束的时间是否在已有的一个时间段之前或者与其相等
            if (classTime.getEndTime().isBefore(firstTimeEntity.getStartTime())
                    || classTime.getEndTime().equals(firstTimeEntity.getStartTime())) {
                return true;
                // 检查新的课程开始的时间是否在已有的一个时间段之后或者与其相等
            } else if (classTime.getStartTime().isAfter(lastTimeEntity.getEndTime())
                    || classTime.getStartTime().equals(lastTimeEntity.getEndTime())) {
                return true;
            } else {
                return false;
            }
        } else {
            System.out.println("进入判断多个时间段");
            // 如果教师的课程安排列表有多个时间段
            // 检查新的课程结束的时间是否在已有的第一个时间段之前或者与其相等
            if (classTime.getEndTime().isBefore(firstTimeEntity.getStartTime())
                    || classTime.getEndTime().equals(firstTimeEntity.getStartTime())
                    || classTime.getStartTime().isAfter(lastTimeEntity.getEndTime())
                    || classTime.getStartTime().equals(lastTimeEntity.getEndTime())) {
                System.out.println("进入判断课程时间段的结束时间在于第一个时间段之前或者开始时间在于最后一个时间段之后");
                return true;
                // 检查新的课程开始的时间是否在已有的第一个时间段之后或者与其相等
            } else if (classTime.getStartTime().isAfter(firstTimeEntity.getEndTime())
                    || classTime.getStartTime().equals(firstTimeEntity.getEndTime())) {
                System.out.println("进入判断多个时间段, 中间时间段");

                // 给定的课程开始时间
                LocalTime st = classTime.getStartTime();//14:30
                LocalTime se = classTime.getEndTime();
                LocalTime closestEndTime = null;
                LocalTime closestStartTime = null;

                //[TimeEntity(startTime=13:35, endTime=15:15), TimeEntity(startTime=09:30, endTime=10:30)]
                // 遍历教师课程安排列表，找到与给定时间最接近的两个时间段
                for (int i = 1; i < teacherSchedule.size(); i++) {
                    //这是是具有多个可成时间, 例如, 结束时间是第一个课程的时间, 开始时间是第二个课程的时间, 所以需要找到两个时间段的中间时间
                    TimeEntity currentEnd = teacherSchedule.get(i);//2
                    TimeEntity currentStart = teacherSchedule.get(i - 1);//1

                    System.out.println("i===>" + i);
                    System.out.println("currentEnd===>" + currentEnd);//2
                    System.out.println("currentStart===>" + currentStart);//1


                    //注意: 这里的teacherSchedule的排序是倒数的, 例: teacherSchedule===>[TimeEntity(startTime=20:00, endTime=20:55), TimeEntity(startTime=18:30, endTime=20:00), TimeEntity(startTime=16:30, endTime=18:00), TimeEntity(startTime=12:00, endTime=13:00), TimeEntity(startTime=09:30, endTime=11:00)]
                    System.out.println("st===>"+st);
                    System.out.println("se===>"+se);
                    //判断该课的开始时间是否在上一个时间段之后, 或者是否等于上一个时间段的结束时间, 并且
                    //         结束时间在下一个时间段之前, 或者是否等于下一个个时间段的开始时间
                    //         则找到了两个时间段的中间时间, 计算时间间隔, 并判断是否可以添加新的课程时间
                    if (st.equals(currentEnd.getEndTime()) || st.isAfter(currentEnd.getEndTime())
                            &&
                            se.equals(currentStart.getStartTime()) || se.isBefore(currentStart.getStartTime())) {

                        closestEndTime = currentEnd.getEndTime();
                        closestStartTime = currentStart.getStartTime();

                        System.out.println("closestEndTime===>" + closestEndTime);
                        System.out.println("closestStartTime===>" + closestStartTime);

                        break;
                    }
                }

                // 如果找不到最接近的两个时间段，则无法添加新的课程时间
                if (closestEndTime == null || closestStartTime == null) {
                    return false;
                }

                // 计算最接近的两个时间段之间的时间间隔
                Duration duration = Duration.between(closestEndTime, closestStartTime);
                Duration classduration = Duration.between(classTime.getStartTime(), classTime.getEndTime());
                long durationMinutes = duration.toMinutes(); // 获取时间间隔的分钟数
                long classMinutes = classduration.toMinutes(); // 获取课程时间的分钟数

                // 打印调试信息
                System.out.println("间隔时间===>" + durationMinutes);
                System.out.println("课程时间===>" + classTime);
                System.out.println("上课时间===>" + classMinutes);
                System.out.println("课程开始时间===>" + classTime.getStartTime());
                System.out.println("课程结束时间===>" + classTime.getEndTime());

                // 如果时间间隔大于等于课程时间，则可以添加新的课程时间
                if (durationMinutes >= classMinutes) {
                    if (classTime.getStartTime().isAfter(closestEndTime) || classTime.getStartTime().equals(closestEndTime)
                            && classTime.getEndTime().isBefore(closestStartTime) || classTime.getEndTime().equals(closestStartTime)) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
    }


}
